//#define _CRTDBG_MAP_ALLOC
#include "StdAfx.h"
#include "SIFTFeature.h"
//#define _CRTDBG_MAP_ALLOC

SIFTFeature::SIFTFeature(void)
{}
SIFTFeature::SIFTFeature(int id,char* cameraIp,float* siftFeatures,int noOfSIFTFeatures,int discriptorSize,IplImage* snapshot,time_t timeStamp)
{
    this->id =id;
    this->cameraIp = cameraIp;
    this->siftFeatures = siftFeatures;
    this->noOfSIFTFeatures = noOfSIFTFeatures;
    this->discriptorSize = discriptorSize;
    this->snapshot=snapshot;
    this->timeStamp=timeStamp;

}
bool SIFTFeature::saveToDB(DBConnect* dbConnect)
{
     string serializedString = getSerializedSIFTFeatures(this->siftFeatures,this->discriptorSize);
    
    int chunkSize = 2*serializedString.length()+1;
    char* chunk=(char*)malloc(sizeof(char)*chunkSize);    
    MYSQL *conn = dbConnect->getConnection();
    mysql_real_escape_string(conn, chunk, serializedString.c_str(), serializedString.length());
    
    //snapshot->imageData;
   // string serializedString = 
    int imageChunkSize = 2*strlen(snapshot->imageData)+1;
    char* chunkSnapShot=(char*)malloc(sizeof(char)*imageChunkSize);    
 //   IplImage* image=snapshot ;
   // MYSQL *conn = dbConnect->getConnection();
    mysql_real_escape_string(conn,chunkSnapShot , snapshot->imageData, strlen(snapshot->imageData));

    char* stat = "INSERT INTO image (camaraIp,siftfeatures,noofsiftfeatures,discriptorSize,snapshot,timestamp) values('%s','%s','%d','%d','%s',now())";
    //char* stat = "INSERT INTO image (camaraIp,siftfeatures,noofsiftfeatures,discriptorSize,timestamp) values('%s','%s','%d','%d',now())";
    //char* stat = "INSERT INTO image (camaraIp,noofsiftfeatures,discriptorSize,timestamp) values('%s','%d','%d',now())";
    char* query=(char*)malloc(sizeof(char)*(strlen(stat)+chunkSize+imageChunkSize));
    //char* query=(char*)malloc(sizeof(char)*(strlen(stat)+strlen(this->cameraIp)+chunkSize));
    //char* query=(char*)malloc(sizeof(char)*(strlen(stat)+strlen(this->cameraIp)));
    int len = sprintf(query,stat,this->cameraIp, chunk,this->noOfSIFTFeatures,this->discriptorSize,chunkSnapShot);    
   // int len = sprintf(query,stat,this->cameraIp, chunk,this->noOfSIFTFeatures,this->discriptorSize);    
    //int len = sprintf(query,stat,this->cameraIp, this->noOfSIFTFeatures,this->discriptorSize);    
  //  int len = sprintf(query,"%s",this->cameraIp); 
     
     /*char query [50];

    int n, a=5, b=3;
    n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
    printf ("[%s] is a %d char long string\n",buffer,n);   */
    
  
    mysql_real_query(conn, query, len);
    //mysql_close(conn);
    free(query);
    free(chunk);
    free(chunkSnapShot);
   // serializedString.clear();

    return true;
}

bool SIFTFeature::loadById(DBConnect* dbConnect,int id)
{
 unsigned long *lengths;
 
    char* sql = "SELECT camaraIp,siftfeatures,noofsiftfeatures,discriptorSize,snapshot,Unix_Timestamp(timestamp) FROM image WHERE id=%d"; //,snapshot
    char* query=(char*)malloc(sizeof(char)*(strlen(sql)+sizeof(int)));
    int len = sprintf(query,sql, id);    
    
    MYSQL *conn = dbConnect->getConnection();
    mysql_query(conn, query);
    MYSQL_RES *result = mysql_store_result(conn);
    MYSQL_ROW  row = mysql_fetch_row(result);
    
    lengths = mysql_fetch_lengths(result);

    float* deSerialFloat=0;
    if(row[0]!=NULL)
    {
        char* rowFromDB = (char*)malloc(sizeof(char)*lengths[0]);
        memcpy(rowFromDB,row[0],(sizeof(char)*lengths[0]));
       // sprintf(rowFromDB,"%s", row[0]);
        

        //deSerialFloat=getDeSeraializedSIFTFeatures(rowFromDB,lengths[0]);
        //this->siftFeatures=getDeSeraializedSIFTFeatures(rowFromDB,lengths[0]);
        this->cameraIp=rowFromDB;
        //free(query);
        free(rowFromDB);
        
        
    //    free(query);
    }
    if(row[1]!=NULL)
    {
        char* rowFromDB = (char*)malloc(sizeof(char)*lengths[1]);
        memcpy(rowFromDB,row[1],(sizeof(char)*lengths[1]));
       // sprintf(rowFromDB,"%s", row[0]);    

        //deSerialFloat=getDeSeraializedSIFTFeatures(rowFromDB,lengths[0]);
        this->siftFeatures=getDeSeraializedSIFTFeatures(rowFromDB,lengths[1]); 
        free(rowFromDB);

    }
    
    if(row[2]!=NULL)
    {
        //char* rowFromDB = (char*)malloc(sizeof(char)*lengths[2]);
        //memcpy(rowFromDB,row[2],(sizeof(char)*lengths[2]));
        ///MYSQL_TYPE_INT24 = 
        this->noOfSIFTFeatures = atoi(row[2]);
        
    }
    if(row[3]!=NULL)
    {
        this->discriptorSize = atoi(row[3]);        
    }
    if(row[4]!=NULL)
    {
   // cvShowImage("snapshot",this->snapshot);
        char* rowFromDB = (char*)malloc(sizeof(char)*lengths[4]);
        memcpy(rowFromDB,row[4],(sizeof(char)*lengths[4]));
        cvReleaseImageData(this->snapshot);
        this->snapshot->imageData = rowFromDB;      
       // cvShowImage("snapshot",this->snapshot);
         free(rowFromDB); 
    }
    if(row[5]!=NULL)
    {
        char* rowFromDB = (char*)malloc(sizeof(char)*lengths[5]);
        memcpy(rowFromDB,row[5],(sizeof(char)*lengths[5]));      
        this->timeStamp = atoi(rowFromDB);
        free(rowFromDB);
    }
    
    free(query);
    mysql_free_result(result);
    
    return deSerialFloat;

}
string SIFTFeature::getSerializedSIFTFeatures(float* siftFeatures,int dimentionsLength){
    ostringstream os;
    int dataLength = sizeof(float) * dimentionsLength;
    os.write(reinterpret_cast<char *> (siftFeatures), dataLength);
    return os.str();
}

float* SIFTFeature::getDeSeraializedSIFTFeatures(const char* str, int dimentionsLength){
   
    int dataLength =  dimentionsLength; //sizeof(float) *
    int floatDataLength = dimentionsLength/sizeof(float);
    float* data = new float[floatDataLength];
    
    string* str2 = new string(str, dataLength);
    istringstream is(*str2);
    is.read(reinterpret_cast<char *> (data), dataLength);
    
    return data;
 }
SIFTFeature::~SIFTFeature(void)
{
     //delete cameraIp;
    // delete siftFeatures;

    // cvReleaseImage(&snapshot);

}